#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import enum
import os
from dataclasses import dataclass
from enum import Enum
from typing import Callable, Tuple

from pydantic import BaseModel, Field

from common.const import RpcParamKey
from common.env_common import adaptation_win_path


def exchagne_install_path():
    """
    功能描述: 适配windows下特殊场景路径
    参数：无
    """
    head_path = os.getenv("ExchangeInstallPath")
    if head_path:
        return head_path.replace("\\", "/")
    return ""


class ParamConstant:
    # 输入参数文件目录
    PARAM_FILE_PATH = f"{adaptation_win_path()}/DataBackup/ProtectClient/Plugins/GeneralDBPlugin/tmp/"
    # 输出结果文件目录
    RESULT_PATH = f"{adaptation_win_path()}/DataBackup/ProtectClient/Plugins/GeneralDBPlugin/stmp/"
    # RPCTool路径
    RPC_TOOL = f"{adaptation_win_path()}/DataBackup/ProtectClient/Plugins/GeneralDBPlugin/bin/rpctool.bat"
    # VssAPI路径
    VSS_TOOL_PATH = f"{adaptation_win_path()}/DataBackup/ProtectClient/Plugins/GeneralDBPlugin/bin/VssTool.exe"
    # Powershell路径
    PS_LOC = "C:/WINDOWS/system32/WindowsPowerShell/v1.0/powershell.exe"
    # PS1脚本路径
    PS1_SCRIPTS_PATH = f"{adaptation_win_path()}/DataBackup/ProtectClient/Plugins/GeneralDBPlugin/bin/applications/" \
                       f"exchange/ps1_scripts/"
    # 虚拟盘路径
    VIRTUAL_PATH = "C:\\BackupTempFile\\"
    # ESEUTIL路径
    ESEUTIL_TOOL_PATH = f"{exchagne_install_path()}/Bin/eseutil.exe"
    # 空数据
    EMPTY_DATA = None
    # 时间戳格式
    RECOVERY_TARGET_TIME_FORMATTER = "%Y-%m-%d %H:%M:%S"
    MNT_PATH = f"{adaptation_win_path()}\\mnt\\databackup"


class JobData:
    PID = None


class ExchangeStrConstant:
    EXCHANGE = "exchange"
    EXCHANGE_INFOMATION_SERVICE = "MSExchangeIS"


class ExchangeType:
    EXCHANGE_DATABASE = "Exchange-database"
    EXCHANGE_GROUP = "Exchange-group"


class TaskStage:
    BACKUP_PREREQUISITE = "BackupPrerequisite"
    BACKUP_GEN_SUB_JOB = "BackupGenSubJob"
    BACKUP = "Backup"


class VSSToolOperation:
    DELETE = "Delete"
    BACKUP = "Backup"


class LogCopyModel(BaseModel):
    job_id: str = Field(default='', description='任务ID')
    sub_job_id: str = Field(default='', description='子任务ID')
    log_min_time: int = Field(default=0, description='可恢复开始时间')
    log_max_time: int = Field(default=0, description='可恢复开始时间')
    snapshot_time: int = Field(default=0, description='快照时间')


class CopyToTimeModel(BaseModel):
    job_id: str = Field(default='', description='任务ID')
    log_start_time: int = Field(default=0, description='可恢复开始时间')
    log_end_time: int = Field(default=0, description='可恢复结束时间')
    job_type: str = Field(default='', description='任务类型')


class ExchangeReportDBLabel:
    # 执行前置任务失败。
    PRE_REQUISIT_FAILED = "plugin_execute_prerequisit_task_fail_label"
    # 子任务（{0}）执行成功。
    SUB_JOB_SUCCESS = "plugin_task_subjob_success_label"
    # 子任务（{0}）执行失败。
    SUB_JOB_FALIED = "plugin_task_subjob_fail_label"
    # 数据保护代理主机（{0}）执行后置任务（{1}）失败。
    POST_TASK_FAIL = "agent_execute_post_task_fail_label"
    # 子任务（{0}）正在执行中，已恢复邮箱({1})：{2} / {3}。
    EXCHANGE_RESTORE_MAILBOX_PROGRESS = "exchange_restore_mailbox_progress_label"
    # 开始执行恢复子任务（{0}）。
    START_RESTORE_LABEL = "plugin_start_restore_copy_subjob_label"
    # 备份完成，{0}封邮件备份成功，{1}封邮件备份失败。
    MAILBOX_BACKUP_PARTIAL_SUCCESS = "plugin_exchange_mailbox_backup_partial_success_label"
    # 备份完成，{0}封邮件备份成功。
    MAILBOX_BACKUP_SUCCESS = "plugin_exchange_mailbox_backup_success_label"
    # 备份进行中，待备份{0}封邮件，已备份{1}封邮件。
    MAILBOX_BACKUP_PROGRESS = "plugin_exchange_mailbox_backup_progress_label"
    # 扫描完成，共扫描{0}封邮件。
    MAILBOX_SCAN_SUCCESS = "plugin_exchange_mailbox_scan_success_label"
    # 扫描进行中，已扫描{0}封邮件。
    MAILBOX_SCAN_PROGRESS = "plugin_exchange_mailbox_scan_progress_label"
    # 恢复完成，{0}封邮件恢复成功，{1}封邮件恢复失败。
    MAILBOX_RESTORE_PARTIAL_SUCCESS = "plugin_exchange_mailbox_restore_partial_success_label"
    # 恢复完成，{0}封邮件恢复成功。
    MAILBOX_RESTORE_SUCCESS = "plugin_exchange_mailbox_restore_success_label"
    # 恢复进行中，已恢复{0}封邮件。
    MAILBOX_RESTORE_PROGRESS = "plugin_exchange_mailbox_restore_progress_label"
    # 数据保护代理主机{x}正在恢复数据，同名数据库{x}验证通过。
    DATABASE_RESTORE_CHECK_SUCCESS = "plugin_exchange_database_restore_check_success_label"
    # 数据保护代理主机{x}执行恢复任务失败，同名数据库{X}不存在。
    DATABASE_RESTORE_CHECK_FAILED = "plugin_exchange_database_restore_check_failed_label"
    # 前置任务任务失败，同名数据库{X}不存在。
    DATABASE_PER_CHECK_FAILED = "plugin_exchange_database_per_check_failed_label"
    # 数据保护代理主机{x}正在恢复数据，数据库{x}可被还原覆盖设置成功。
    DATABASE_ALLOW_RESTORE_SUCCESS = "plugin_exchange_database_allow_restore_success_label"
    # 数据保护代理主机{x}执行恢复任务失败，数据库{x}可被还原覆盖设置失败。
    DATABASE_ALLOW_RESTORE_FAILED = "plugin_exchange_database_allow_restore_failed_label"
    # 数据保护代理主机{x}正在恢复数据，可用性组数据库{x}被动副本复制、重播、激活属性设置成功。
    DATABASE_SET_RESTORE_SUCCESS = "plugin_exchange_database_set_restore_success_label"
    # 数据保护代理主机{x}执行恢复任务失败，可用性组数据库{x}被动副本复制、重播、激活属性设置失败。
    DATABASE_SET_RESTORE_FAILED = "plugin_exchange_database_set_restore_failed_label"
    # 数据保护代理主机{x}正在恢复数据，数据库{x}卸载成功。
    DATABASE_RESTORE_DISMOUNT_SUCCESS = "plugin_exchange_database_restore_dismount_success_label"
    # 数据保护代理主机{x}执行恢复任务失败，数据库{x}卸载失败。
    DATABASE_RESTORE_DISMOUNT_FAILED = "plugin_exchange_database_restore_dismount_failed_label"
    # 数据保护代理主机{x}执行恢复任务失败，数据库{x}未卸载。
    DATABASE_RESTORE_UNMOUNT = "plugin_exchange_database_restore_unmount_label"
    # 数据保护代理主机{x}正在恢复数据，数据库{x}执行解除挂载成功。
    DATABASE_RESTORE_UNMOUNT_SUCCESS = "plugin_exchange_database_restore_unmount_success_label"
    # 数据保护代理主机{x}执行恢复任务失败，数据库{x}执行解除挂载失败。
    DATABASE_RESTORE_UNMOUNT_FAILED = "plugin_exchange_database_restore_unmount_failed_label"
    # 数据保护代理主机{x}正在恢复数据，数据库{x}执行vsstool恢复成功。
    DATABASE_RESTORE_VSS_SUCCESS = "plugin_exchange_database_restore_vss_success_label"
    # 数据保护代理主机{x}执行恢复任务失败，数据库{x}执行vsstool恢复失败。
    DATABASE_RESTORE_VSS_FAILED = "plugin_exchange_database_restore_vss_failed_label"
    # 数据保护代理主机{x}正在恢复数据，数据库{x}装载成功。
    DATABASE_RESTORE_MOUNT_SUCCESS = "plugin_exchange_database_restore_mount_success_label"
    # 数据保护代理主机{x}执行恢复任务失败，数据库{x}装载失败。
    DATABASE_RESTORE_MOUNT_FAILED = "plugin_exchange_database_restore_mount_failed_label"
    # 数据保护代理主机{x}正在恢复数据，数据库{x}恢复完成。
    DATABASE_RESTORE_SUCCESS = "plugin_exchange_database_restore_success_label"
    # 数据保护代理主机{x}正在恢复数据，数据库{x}恢复失败。
    DATABASE_RESTORE_FAILED = "plugin_exchange_database_restore_failed_label"
    # 数据保护代理主机{x}创建快照成功。
    DATABASE_BACKUP_SNAPSHOT_SUCCESS = "plugin_exchange_database_backup_snapshot_success_label"
    # Exchange正在执行日志恢复，此次用户选择恢复时间点为({0})，实际恢复的文件为({1})，该文件对应的实际恢复的时间范围为({2})到({3})。
    DATABASE_BACKUP_RESTORE_TIME_INFO_SUCCESS = "plugin_exchange_database_restore_time_info_label"
    # Exchagne日志备份时，数据库({0})未执行过全量备份，此次任务转为全量备份。
    DATABASE_BACKUP_LOG_TO_FULL_SUCCESS = "plugin_exchange_database_restore_log_to_full_info_label"
    # 数据保护代理主机{x}创建快照失败。
    DATABASE_BACKUP_SNAPSHOT_FILED = "plugin_exchange_database_backup_snapshot_filed_label"
    # 数据保护代理主机{x}正在备份数据，待备份{x}个数据库。
    DATABASE_BACKUP_NUMBER = "plugin_exchange_database_backup_number_label"
    # 数据保护代理主机{x}正在备份数据，数据库{x}{x}副本备份成功。
    DATABASE_BACKUP_SUCCESS = "plugin_exchange_database_backup_success_label"
    # 数据保护代理主机{x}执行备份任务失败，数据库{x}{X}副本备份失败。
    DATABASE_BACKUP_FAILED = "plugin_exchange_database_backup_failed_label"
    # 数据库{x}创建成功
    DATABASE_CREATE_SUCCESS = "plugin_exchange_database_create_success_label"
    # 数据库{x}创建失败
    DATABASE_CREATE_FAILED = "plugin_exchange_database_create_failed_label"
    # 副本校验失败。
    COPY_VERIFICATION_FAILED = "plugin_task_copy_verification_fail_label"


class BodyErr(Enum):
    # 输入的用户名或者密码错误
    LOGIN_FAILED = 0x64032C10  # 1677929488
    # 执行备份操作时，由于数据库存在未运行的服务，操作失败
    ERR_DB_SERVICES = 0x5E025E27  # 1577213479
    # 插件鉴权失败
    EXCHANGE_AUTH_INFO_ERROR = 0x64032B0C  # 1677929228
    # 来自sqlserver
    ERR_PLUGIN_CANNOT_BACKUP = 0x64032B0C  # 1677929228
    ERR_INC_TO_FULL = 0x5E02502D  # 1577209901
    ERROR_COMMON_INVALID_PARAMETER = 0x5F025102
    SQLSERVER_REGISTER_TYPE_ERROR = 0x5E0250D4  # 1577210068
    SQLSERVER_AUTH_INFO_ERROR = 0x5E0250D6  # 1577210070
    ERROR_INTERNAL = 0x5F025101  # 1593987329
    RESTORE_FAIL_FOR_DATABASE_EXIST = 0x5E0250E7  # 1577210087
    RESTORE_FAIL_FOR_DATABASE_FILE_EXIST = 0x5E0250E8  # 1577210088
    RESTORE_FAIL_FOR_ALWAYSON_EXIST = 0x5E0250E9  # 1577210089
    RESTORE_FAIL_FOR_VERSION_INCONSISTENCY = 0x5E0250EA  # 1577210090
    RESTORE_FAIL_FOR_NODE_NOT_MEET = 0x5E0250EB  # 1577210091
    RESTORE_FAIL_FOR_PATH_NOT_EXIST = 0x5E0250EC  # 1577210092
    BACKUP_FAIL_FOR_FULL_BACKUP_NEED = 0x5E0250F0  # 1577210096
    SQLSERVER_DATABASE_IN_USE_ERROR = 0x5E0250F1  # 1577210097
    SQLSERVER_REVERTIVE_MODE_ERROR = 0x5E0250DA  # 1577210074
    SQLSERVER_PERMISSIONS_ERROR = 0x5E0250DB  # 1577210075
    BACKUP_FAIL_FOR_DATABASE_STATE_ABNORMAL = 0x5E0250EF  # 1577210095 数据库状态异常
    BACKUP_FAIL_FOR_LAST_LOG_FAIL = 0x5E0250DE
    SQLSERVER_DATABASE_NAME_INVALID = 0x5E0250F6
    INSTANCE_STATE_ABNORMAL = 0x5E025E16
    RESOURCE_NOT_EXIST = 0x64034212  # 1677935122 资源不存在
    ALL_DATABASE_NOT_EXIST = 1577085697  # 1577213447 没有可备份的数据库
    EXCHANGE_WRITER_IS_NOT_STABLE = 1577085696  # Microsoft Exchange Writer状态异常
    CREATE_SNAPSHOT_FILED = 1577085698  # 创建快照失败
    CHECK_SNAPSHOT_FILED = 1577085699  # 一致性校验失败
    MAILBOX_ERROR_NO_IMPERSONATE_USER = 0x5E025E80  # 用户未赋予ApplicationImpersonation角色
    DB_USER_RESTORE_TAR_MAILBOX_NOT_EXIST = 0x5E006B04  # 执行Exchange数据库用户级恢复时，由于目标邮箱不存在，操作失败。
    EMAIL_EXCEED_SIZE_LIMIT = 0x5E025E81  # 1577213569 执行Exchange邮箱备份时，由于部分邮件大小超过限制，操作失败。
    # 0x5E035C01 执行Exchange恢复操作时，由于已存在目标数据库，并且输入的数据库文件和日志文件路径和目标数据库现有的数据库文件和日志文件路径不一致，操作失败。
    EDB_AND_LOG_PATH_SAME_CHECK_FAILED = 0x5E035C01
    # 0x5E025401 执行exchange恢复操作时，由于生成副本的主机版本信息与目标主机的版本信息不一致，操作失败
    EXCHANGE_IS_INCONSISTENT = 1577210881
    EXCHANGE_NO_DISK_SPACE = 1577085702
    # 0x5E006B07 执行Exchange恢复时，由于在同一见证服务器下的不同服务器上存在同名数据库，数据恢复失败。
    DATABASE_EXIST_IN_OTHER_SERVER = 1577085703
    # 备份副本中元数据文件不存在
    COPY_META_DATA_NOT_EXIST = 1577085701
    # 执行备份校验操作时，由于增量备份依赖的备份副本元数据损坏，操作失败。
    EXCHANGE_CHECK_DEPENDENCE_COPY_FAILED = 1577085704
    # 系统异常
    SYSTEM_ERROR = 1677929221


class LastCopyType:
    last_copy_type_dict = {
        1: [RpcParamKey.FULL_COPY, RpcParamKey.PERMANENT_INCREMENTAL_COPY],
        2: [RpcParamKey.FULL_COPY],
        3: [RpcParamKey.LOG_COPY],
        4: [RpcParamKey.FULL_COPY, RpcParamKey.PERMANENT_INCREMENTAL_COPY, RpcParamKey.LOG_COPY]
    }


class CopyType:
    DATA_COPY = 1
    FULL_COPY = 2
    LOG_COPY = 3
    ALL_COPY = 4


class ExchangeCode(Enum):
    SUCCESS = 0
    FAILED = 200


class ExchangeWindowsPath:
    UNC = "\\\\?\\"
    VSS_PATH_Prefix = "\"\\"
    VSS_PATH_MARKS = "\""


class ExchangeBackupType:
    EXCHANGE_BACKUP_FULL = "full"
    EXCHANGE_BACKUP_INC = "inc"


class ExchangeJobType:
    job_type_dict = {
        1: "Backup",
        2: "Backup",
        4: "Log",
        6: "Backup"
    }


class JobBackupType:
    EXCHANGE_BACKUP_FULL = 1
    # 增量
    EXCHANGE_BACKUP_INC = 2
    # 永久增量
    EXCHANGE_BACKUP_FOREVER_INC = 6
    EXCHANGE_BACKUP_LOG = 4


class ExchangeServiceStatus:
    STOPPED = 1
    START_PENDING = 2
    STOP_PENDING = 3
    RUNNING = 4
    CONTINUE_PENDING = 5
    PAUSE_PENDING = 6
    PAUSED = 7


class ExchangeDatabaseCopyStatus:
    DISMOUNTED = 12
    MOUNTED = 11
    Suspended = 5
    Healthy = 6


class ExecCmdResult:
    SUCCESS = "0"
    ERROR = "-1"
    UNKNOWN_CMD = "-2"


class SubJobStatusEnum(int, Enum):
    INITIALIZING = 0
    RUNNING = 1
    ABORTING = 2
    COMPLETED = 3
    ABORTED = 4
    ABORTED_FAILED = 5
    FAILED = 6
    FAILED_NOTRY = 7
    PARTIAL_COMPLETED = 13


class ProgressConst(int, Enum):
    MIN_PROGRESS = 5
    INSTANCE_MAX_PROGRESS = 90
    DATABASE_MAX_PROGRESS = 95
    PROGRESS_ONE_HUNDRED = 100


class SubJobPolicy(int, Enum):
    LOCAL_NODE = 1,
    EVERY_NODE_ONE_TIME = 2,
    RETRY_OTHER_NODE_WHEN_FAILED = 3,
    FIXED_NODE = 4


class SubJobType(int, Enum):
    PRE_SUB_JOB = 0,
    GENERATE_SUB_JOB = 1,
    BUSINESS_SUB_JOB = 2,
    POST_SUB_JOB = 3


class SubJobPriorityEnum(int, Enum):
    JOB_PRIORITY_1 = 1
    JOB_PRIORITY_2 = 2
    JOB_PRIORITY_3 = 3
    JOB_PRIORITY_4 = 4
    JOB_PRIORITY_5 = 5


class ExchangeBackupSubJobName:
    SUB_EXEC = "sub_exec_back"
    SUB_UPLOAD = "sub_upload_back"


class ExchangeRestoreSubJobName:
    SUB_EXEC = "sub_exec_restore"


SYSTEM_MAILBOX_LIST = [
    # https://learn.microsoft.com/zh-cn/exchange/recipients-exchange-2013-help
    "SystemMailbox {bb558c35-97f1-4cb9-8ff7-d53741dc928c}",  # 组织

    "SystemMailbox {e0dc1c29-89c3-4034-b678-e6c29d823ed9}",  # UM 数据存储

    "DiscoverySearchMailbox {D919BA05-46A6-415f-80AD-7E09334BB852}",  # 发现

    "FederatedEmail.4c1f4d8b-8179-4148-93bf-00a95fa1e042",  # 联合电子邮件

    "Migration.8f3e7716-2011-43e4-96b1-aba62d229136",  # 迁移,

    # 邮件审批,完整格式为SystemMailbox {1f05a927-xxxx-xxxx xxxx--xxxxxxxxxxxx}
    # 其中 x 是每个 Exchange 林的随机分配且唯一的数字
    "SystemMailbox {1f05a927",
]


@dataclass
class ExchangeJobInfo:
    """
    任务相关参数信息
    """
    job_id: str
    # 恢复或者备份
    copy_id: str = None
    type: str = None
    pid: str = None
    usr: str = None
    env_path: str = None
    sub_job_id: str = None
    sub_job_type: str = None
    cache_path: str = None
    meta_path: str = None
    meta_rep: dict = None
    cache_rep: dict = None
    data_reps: list = None
    metadata_destination: str = None
    backup_type: int = None
    progress: int = None
    task_status: int = None
    backup_result: int = None
    storage_id: str = None
    protect_env: dict = None
    backup_tool_type: int = None
    res_name: str = None
    nodes: list = None
    pro_obj_extend_info: dict = None
    pro_obj: dict = None
    storage_esn: set = None
    agents: list = None
    failed_agents: list = None
    cluster_agents: list = None
    host_agents: list = None
    open_source_delete: bool = False  # 此次备份是否开启源端重删
    storage_type: str = None
    min_log_time: int = None
    max_log_time: int = None
    snapshot_time: int = None
    restore_begin_time: int = None
    restore_end_time: int = None
    restore_target_time: int = None
    restore_file: int = None
    restore_db_name: str = None

    def log_format(self):
        """
        功能： 日志格式化返回
        """
        return f"pid: {self.pid}, job_id: {self.job_id}, sub_job_id: {self.sub_job_id}"

    def log_usr_env_path_format(self):
        return f"usr: {self.usr}, env_path: {self.env_path}"


class ExchangeMailBosConstants:
    FULL_BACKUP = "Full_Backup"
    INC_BACKUP = "Incremental_Backup"
    META_DIR = "meta"


class ExchangeRestoreType:
    EXCHANGE_RESTORE_DATABASE = "Exchange-database"
    EXCHANGE_RESTORE_GROUP = "Exchange-group"


class ExchangeRestoreTargetType:
    SINGLE = "0"
    DAG = "1"


class ExchangeRestoreLocation:
    ORIGIN = "original"
    NEW = "new"


class ExchangeRestoreAction(enum.Enum):
    REJECT = 0
    OVERWRITE = 1
    RESTORE = 2


class RestoreSubJobName:
    ACTUALL_RESTORE = "actual_restore"


class DataBackupType(enum.IntEnum):
    FULL_BACKUP = 0
    INCREMENT_BACKUP = 1


class RepositoryDataTypeEnum(int, Enum):
    META_REPOSITORY = 0
    DATA_REPOSITORY = 1
    CACHE_REPOSITORY = 2
    LOG_REPOSITORY = 3
    INDEX_REPOSITORY = 4
    LOG_META_REPOSITORY = 5


class CopyDataTypeEnum(str, Enum):
    # 副本类型
    FULL_COPY = "full"
    INCREMENT_COPY = "increment"
    DIFF_COPY = "diff"
    LOG_COPY = "log"
    S3_ARCHIVE = "s3Archive"
    TAP_ARCHIVE = "tapeArchive"
    CLONE = "clone"


class PathSymbol:
    QUOTATION = "\""
    SLASHES = "\\"
    MAILBOX_PREFIX = "MailboxDatabase_"


class ExchangeCopyType:
    ACTIVE = "exchange_active_copy_label"
    PASSIVE = "exchange_passive_copy_label"


class CreateSoftLink(BaseModel):
    src_path: str = Field(description="源路径")
    dst_path: str = Field(description="目标路径")
    src_user: str = Field(None, description="目标路径所属用户")
    src_path_check_func: Callable = Field(None, description="源路径校验函数")
    src_path_check_func_args: Tuple = Field(None, description="源路径校验函数参数")
    dst_path_check_func: Callable = Field(None, description="目标路径校验函数")
    dst_path_check_func_args: Tuple = Field(None, description="目标路径校验函数参数")


class AgentConstant:
    RETRY_TIMES = 3
    RETRY_WAIT_SECONDS = 35
    THREE_DECIMAL_PLACES = 3
    UNITS = {
        1: str('Byte'), 2: str('KB'), 3: str('MB'), 4: str('GB'), 5: str('TB'),
        6: str('PB'), 7: str('EB'), 8: str('ZB'), 9: str('YB')
    }


class ExchangeProgressPhase(int, Enum):
    RESTORE_STEP_ONE = 1
    RESTORE_STEP_TOW = 2
    RESTORE_STEP_THREE = 3
    RESTORE_PHASE = 3
    TASK_COMPLETE = 100


WAITE_TIME = 5

# 备份所需磁盘容量百分比
PERCENT = 5

# 重试间隔
RETRY_WAIT_SECONDS = 60

# 重试
RETRY_COUNT = 3
